//
// Created by benxb on 2021/11/3.
//

#ifndef BENXDB_COMPRESSOR_H
#define BENXDB_COMPRESSOR_H

#include <cstdio>
#include <type/type_id.h>
#include <stdint-gcc.h>

namespace benxdb {

class Compressor {
public:
    explicit Compressor() = default;
    ~Compressor() = default;

    bool DeltaEncode(char *in, size_t in_len, TypeId type, std::string& out);

    /**
     * Encode data_ in big int format
     * @param in input bit int string
     * @param in_len input data_ length
     * @param out encoded data_
     * @return true if successfully encoded
     */
    bool DeltaEncodeBigInt(char *in, size_t in_len, std::string& out);

    /**
     * Decode big int string from compressed data_
     * @param in compressed data_
     * @param in_len compressed data_ length
     * @param out decompressed data_
     * @return true if successfully decoded
     */
    bool DeltaDecodeBigInt(char *in, size_t in_len, std::string& out);

    bool DeltaDecode(char *in, size_t in_len, TypeId type, std::string& out);

    int64_t GetMaxValue();

    int64_t GetMinValue();

    /**
     * find the max and min value from given string
     * @param in given string
     * @param len string len
     * @param max_value
     * @param min_value
     */
    void GetMaxMinInt64(char *in, size_t len, int64_t& max_value, int64_t& min_value);

    /**
     * Encode data_ in decimal format
     * @param in input bit int string
     * @param in_len input data_ length
     * @param precision max digit after decimal point
     * @param out encoded data_
     * @return true if successfully encoded
     */
    bool DeltaEncodeDecimal(char *in, size_t len, int8_t precision, std::string &basicString);

    /**
     * Encode data_ in float format
     * @param in input bit int string
     * @param in_len input data_ length
     * @param precision max digit after decimal point
     * @param out encoded data_
     * @return true if successfully encoded
     */
    bool DeltaEncodeFloatWithPadding(char *in, size_t in_len, int8_t precision, std::string &out);

    /**
     * Decode decimal string from compressed data_
     * @param in compressed data_
     * @param in_len compressed data_ length
     * @param out decompressed data_
     * @return true if successfully decoded
     */
    bool DeltaDecodeDecimal(char *in, size_t len, std::string &basicString);

    /**
     * Get max number of digit after point
     * @param in input data_ in binary format
     * @param len input data_ length
     * @return the number of digit
     */
    int8_t GetPrecision(char *in, size_t len);

    bool DeltaEncodeBigIntWithPadding(char *in, size_t in_len, std::string &out);

    bool DeltaEncodeInt32WithPadding(char *in, size_t in_len, std::string &out);

    void GetMaxMinInt32(char *in, size_t len, int32_t &max_value, int32_t &min_value);

    bool DeltaEncodeDecimalWithPadding(char *in, size_t in_len, int8_t precision, std::string &out);

    bool DeltaEncodeInt(char *in, size_t len, std::string& out);

    bool DeltaEncodeFloat(char *in, size_t in_len, int8_t precision, std::string &out);

    bool DeltaDecodeFloat(char *in, size_t in_len, std::string &out);

    bool DeltaDecodeInt(char *in, size_t in_len, std::string &out);
};

}


#endif //BENXDB_COMPRESSOR_H
